package com.martinprobst.xqpretty;

import org.antlr.runtime.RecognitionException;



public class Bench {

  public static void main(String[] args) {
    String query = "module namespace util = \"http://hpl.hp.com/wiki/util\";  \n"
        + "\n"
        + "\n"
        + "declare function util:index-scan ($index-name, $name, $rel) as node()* \n"
        + "{\n"
        + "  if ('article-by-title' = $index-name) then doc('/wiki')/root/page[title=$name]\n"
        + "  else if ('article-by-id' = $index-name) then doc('/wiki')/root/page[id=$name]\n"
        + "  else if ('link-by-target' = $index-name) then doc('/wiki')/root/page/links/link[@label = $name]\n"
        + "  else if ('article-by-cat' = $index-name) then doc('/wiki')/root/page/catlinks/catlink[@label=$name]\n"
        + "  else error (concat('Unknown index ', $index-name))\n"
        + "};\n"
        + "\n"
        + "declare function util:get-subconcepts ($name as xs:string) as element()*\n"
        + "{\n"
        + "  for $sec in util:index-scan('section-by-name', $name, 'EQ')\n"
        + "  let $p := $sec/ancestor::page\n"
        + "  where fn:exists (for $rl in util:index-scan('link-by-target', fn:concat (fn:concat(fn:string($p/title), '#'), fn:string ($sec)), 'EQ')\n"
        + "                   where  ($rl/ancestor::page ne $p)\n"
        + "                   return $rl)\n"
        + "  return $sec\n"
        + "};\n"
        + "\n"
        + "declare function util:is-concept ($name as xs:string) as xs:boolean\n"
        + "{\n"
        + "  if (fn:empty(util:index-scan('article-by-title', $name, 'EQ')))\n"
        + "  then fn:exists(util:get-subconcepts($name))\n"
        + "  else fn:true()\n"
        + "};\n"
        + "\n"
        + "\n"
        + "declare function util:articles-by-category-rec-internal ($title as xs:string, $max-depth as xs:integer, $path as xs:string*) as xs:string* {\n"
        + "        if (($max-depth = 0 or $max-depth > 0) and (count ($path) > $max-depth)) then ()              \n"
        + "        else if (count(index-of($path, $title)) > 1) then ()  (: prevent infinite recursion :)\n"
        + "        else \n"
        + "        (for $page in util:index-scan('article-by-cat', $title, 'EQ')\n"
        + "        let $ptitle := $page/title/text()\n"
        + "        return\n"
        + "                (if (fn:starts-with($ptitle, \"Category:\"))\n"
        + "                then (util:articles-by-category-rec-internal($ptitle, $max-depth, ($path, $ptitle)))\n"
        + "                else $ptitle))\n"
        + "};\n"
        + "\n"
        + "\n"
        + "declare function util:expand-category ($title as xs:string, $max-depth as xs:integer) as xs:string* {\n"
        + "        util:articles-by-category-rec-internal($title, $max-depth, ())\n"
        + "};\n"
        + "\n"
        + "\n"
        + "declare function util:get-nodes-by-heading ($page as element(), $header as element()?) as element()* {\n"
        + "        let $section-tags := (\"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\")\n"
        + "        let $larger-tags := (\n"
        + "           if (empty($header)) then $section-tags else subsequence ($section-tags, 1, index-of($section-tags, name($header)) [1])\n"
        + "        ) \n"
        + "        return if (empty($header)) then (\n"
        + "            let $next-header := $page/body/*[name() = $larger-tags][1]\n"
        + "            return if (empty($next-header)) then ($page/body/*) else ($page/body/*[. << $next-header])\n"
        + "        ) else (\n"
        + "            let $next-header := $page/body/*[name() = $larger-tags][. >> $header][1]\n"
        + "            return if (empty($next-header)) then ($page/body/*[. >> $header]) else ($page/body/*[. >> $header][. << $next-header])\n"
        + "        )\n"
        + "};\n"
        + "\n"
        + "\n"
        + "declare function util:is-redirect ($a as element(page)?) as xs:string? {\n"
        + "        let $redirect-link := $a/links/link[./@isRedirect = 'true'][1]\n"
        + "        return if (exists ($redirect-link) and\n"
        + "                        ((count($a/links/link) = 1) or \n"
        + "                        (exists($a/catlinks/catlink) and (every $cat in $a/catlinks/catlink/@label satisfies (contains (lower-case($cat), 'redirect'))))) \n"
        + "                  ) then $redirect-link/@label else ()\n"
        + "};\n"
        + "\n"
        + "declare function util:get-article-redirect-aware-rec ($title as xs:string, $visited as xs:string*) as element(page)* {\n"
        + "        if (exists(index-of($visited, $title))) \n"
        + "        then () \n"
        + "        else (\n"
        + "                let $a := util:index-scan ('article-by-title', $title, 'EQ')\n"
        + "                let $redirect := util:is-redirect ($a)  \n"
        + "                return if (exists($redirect)) then util:get-article-redirect-aware-rec ($redirect, ($visited, $title))\n"
        + "                                              else $a\n"
        + "        )\n"
        + "};\n"
        + "\n"
        + "declare function util:get-article-by-title ($title as xs:string) as element(page)* {\n"
        + "        util:get-article-redirect-aware-rec ($title, ())\n"
        + "};\n"
        + "\n"
        + "declare function util:make-plural ($word as xs:string) as xs:string {\n"
        + "  if (string-length($word) < 2) then $word\n"
        + "  else if (ends-with ($word, \"ies\") or ends-with($word, \"xes\") or ends-with ($word, \"sses\")) then $word\n"
        + "  else if (ends-with ($word, \"s\") and not(ends-with ($word, \"ss\")) and not(ends-with ($word, \"us\")) and not (ends-with($word, \"is\"))) then $word\n"
        + "  else if (ends-with ($word, \"y\")) then concat (substring ($word, 1, string-length ($word) - 1), \"ies\")\n"
        + "  else if (ends-with ($word, \"x\") or ends-with ($word, \"ss\")) then concat ($word, \"es\")\n"
        + "  else concat ($word, \"s\")\n"
        + "};\n"
        + "\n"
        + "declare function util:capitalize ($word as xs:string) as xs:string {\n"
        + "  if (string-length ($word) = 0) then $word\n"
        + "  else concat (upper-case (substring ($word, 1, 1)), substring ($word, 2))\n"
        + "};\n"
        + "\n"
        + "declare function util:trim-left ($s as xs:string) as xs:string {\n"
        + "  if (string-length ($s) = 0 or (' ' ne substring ($s, 1, 1))) then $s\n"
        + "  else util:trim-left (substring ($s, 2))\n"
        + "};\n"
        + "\n"
        + "declare function util:count-chars ($s as xs:string, $char as xs:string) as xs:integer {\n"
        + "  let $length := string-length ($s)   \n"
        + "  return  sum  (for $i in (1 to $length)\n"
        + "                let $c := substring ($s, $i, 1)\n"
        + "                return if ($c = $char)  then 1\n"
        + "                                        else 0) \n"
        + "\n"
        + "};\n"
        + "\n"
        + "declare function util:normalize-catlink ($catlink as xs:string) as xs:string {\n"
        + "  let $category-prefix := 'Category:'\n"
        + "  return if (count(string-to-codepoints($catlink)[.=58]) = 1)\n"
        + "         then ( \n"
        + "                let $tokenized := tokenize ($catlink, ':')\n"
        + "                return concat ($category-prefix, util:trim-left (util:capitalize ($tokenized [2])))\n"
        + "              )\n"
        + "         else $catlink\n"
        + "};\n"
        + "\n"
        + "\n"
        + "declare function util:get-all-categories() as xs:string* {\n"
        + "  let $last-char := codepoints-to-string (32000)\n"
        + "  let $upper-bound := concat ('Category:', $last-char)\n"
        + "  return doc('/wiki')/root/page[title[. >= 'Category: ' and . <= $upper-bound]]/title/text()\n"
        + "};\n" + "";
    try {
      // warmup
      for (int i = 0; i < 100; i++) {
        Formatter.parse(query);
      }
      // bench
      long ms = System.currentTimeMillis();
      for (int i = 0; i < 100; i++) {
        Formatter.parse(query);
      }
      ms = System.currentTimeMillis() - ms;

      System.out.println("Parsed successfully, avg " + (double)ms / 100 + " ms");
    } catch (RecognitionException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
}
